﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Text;
using System.Threading;
using NPoco;
using Bussiness;
using Models;
using AttendanceDataInteraction;

namespace AttendanceDataInteraction
{
    public class ImportAttendanceData
    {

        public static void ImportData(object source, System.Timers.ElapsedEventArgs e)
        {
            try
            {
                LogHelper.Info(typeof(ImportAttendanceData), "开始导入数据");
                int timeOut = 1000 * 60;
                if (System.Configuration.ConfigurationManager.AppSettings["ImportDataTimeOut"] != null)
                {
                    timeOut = Convert.ToInt32(System.Configuration.ConfigurationManager.AppSettings["ImportDataTimeOut"]);
                }
                CallWithTimeout(LeadAttendanceData, timeOut);
            }
            catch (Exception ex)
            {
                LogHelper.Error(typeof(ImportAttendanceData), "代码报错", ex);
            }
        }

       public static void LeadAttendanceData()
        {
            //昨天数据是否导入
            bool isExist = false;
            DateTime beginTime = Convert.ToDateTime("2010-01-01 01:01:01");
            FP_TB_AttendanceSyncBusiness businessDao = new FP_TB_AttendanceSyncBusiness();
          
            NPoco.Page<FP_TB_AttendanceSync> arr = businessDao.GetListByPage(1, 1, " order by TouchTime desc");
            if (arr.Items.Count > 0)
            {
                DateTime dt = arr.Items[0].TouchTime == null ? beginTime : Convert.ToDateTime(arr.Items[0].TouchTime);
                DateTime kq = Convert.ToDateTime(DateTime.Now.ToString("yyyy-MM-dd")).AddDays (-1).AddMilliseconds(1);
                if (dt > kq)
                {
                    isExist = true;
                }
                else
                {
                    beginTime = dt;
                }
            }
            //没有考勤的进行考勤，考勤开始时间从考勤同步表最近的时间开始
            if (!isExist)
            {
                AttendanceManager mgr = new AttendanceManager();
                DateTime endTime = Convert.ToDateTime(DateTime.Now.ToString("yyyy-MM-dd")).AddMilliseconds(-1);
                List<AttendanceEntity> list = mgr.GetAttendance(beginTime, endTime);
                FP_TB_EmployeeBusiness employeeDao = new FP_TB_EmployeeBusiness();
                FP_TB_AttendanceSortBusiness sortDao = new FP_TB_AttendanceSortBusiness();
                FP_TB_AttendanceSyncBusiness syncDao = new FP_TB_AttendanceSyncBusiness();
                List<FP_TB_Employee> employees = employeeDao.GetListByPage(1, 10000).Items;
                var list2 = list.GroupBy(x => new { x.EmployeeName, AttendanceDate = x.AttendanceTime.ToString("yyyy-MM-dd") }).Select(x => new { WorkBeginTime = x.Min(y => y.AttendanceTime), WorkEndTime = x.Max(y => y.AttendanceTime), x.Key.EmployeeName, x.Key.AttendanceDate }).ToList();
                foreach (var l in list)
                {
                    FP_TB_Employee employee = employees.Where(x => x.ChineseName == l.EmployeeName).FirstOrDefault();
                    FP_TB_AttendanceSync entity = new FP_TB_AttendanceSync();
                    entity.EmployeeName = l.EmployeeName;
                    entity.TouchTime = l.AttendanceTime;
                    if (employee != null)
                    {
                        entity.Department = employee.DepartmentName;
                        entity.EmployeeNumber = employee.EmployeeNumber;
                    }
                    syncDao.Add(entity);
                }
                foreach (var l in list2)
                {
                    FP_TB_Employee employee = employees.Where(x => x.ChineseName == l.EmployeeName).FirstOrDefault();
                    FP_TB_AttendanceSort entity = new FP_TB_AttendanceSort();
                    entity.EmployeeName = l.EmployeeName;
                    entity.WorkBenginTime = l.WorkBeginTime;
                    entity.WorkEndTime = l.WorkEndTime;
                    entity.Month = Convert.ToDateTime(l.AttendanceDate).Month;
                    entity.Year = Convert.ToDateTime(l.AttendanceDate).Year;
                    entity.WorkDate = Convert.ToDateTime(l.AttendanceDate);
                    entity.SortTime = DateTime.Now;
                    entity.OvertimeLength = 9m;
                    if (employee != null)
                    {
                        entity.Department = employee.DepartmentName;
                        entity.DepartmentID = employee.DepartmentID;
                        entity.EmployeeID = employee.ID;
                        entity.EmployeeNumber = employee.EmployeeNumber;
                    }
                    LeadWorkTime(entity);
                    sortDao.Add(entity);
                }
            }
        }
       public static void LeadWorkTime(FP_TB_AttendanceSort entity)
       {
           DateTime beginTime = entity.WorkBenginTime == null ? DateTime.MinValue : Convert.ToDateTime(entity.WorkBenginTime);
           DateTime endTime = entity.WorkEndTime == null ? DateTime.MinValue : Convert.ToDateTime(entity.WorkEndTime);
           if (beginTime == DateTime.MinValue || endTime == DateTime.MinValue) return;
           //休息时间
           TimeSpan totalTime = new TimeSpan(endTime.Ticks) - new TimeSpan(beginTime.Ticks);

           DateTime beginRestTime = Convert.ToDateTime(beginTime.ToString("yyyy-MM-dd") + " 12:00:00");
           DateTime endRestTime = Convert.ToDateTime(beginTime.ToString("yyyy-MM-dd") + " 13:00:00");
           DateTime getoffTime = Convert.ToDateTime(beginTime.ToString("yyyy-MM-dd") + " 18:00:00");
           DateTime OvertimeTime = Convert.ToDateTime(beginTime.ToString("yyyy-MM-dd") + " 19:00:00");
           int week = Convert.ToInt32(beginTime.DayOfWeek.ToString("d"));

           //中午休息一小时
           TimeSpan restTime = new TimeSpan(1, 0, 0);
           //正常工作日
           if (week > 0 && week < 6)
           {
               ////暂时用不到
               //if (beginTime.Hour < 9 && beginTime.Minute < 5)
               //{
               //    beginTime = Convert.ToDateTime(beginTime.ToString("yyyy-MM-dd") + " 09:00:00");
               //}
               if (beginTime >= endRestTime || endTime <= beginRestTime)
               {
                   //没有休息时间的
                   restTime = new TimeSpan(0, 0, 0);
               }
               else if (beginTime <= endRestTime && beginTime >= beginRestTime && endTime > endRestTime)
               {
                   //休息时间才上班
                   restTime = endRestTime - beginTime;
               }
               else if (endTime <= endRestTime && endTime >= beginRestTime && beginTime < beginRestTime)
               {
                   //休息时间就下班
                   restTime = endTime - beginRestTime;
               }
               else if (beginTime <= endRestTime && beginTime >= beginRestTime && endTime <= endRestTime && endTime > beginRestTime)
               {
                   //全是休息时间
                   entity.OvertimeLength = 0m;
                   entity.AbsoluteWorkTime = 0m;
                   return;
               }
               else
               {
                   //正常休息一小时
               }
           }
           //周末加班，没有休息时间，全部都算加班时间
           else
           {
               TimeSpan workSpan = totalTime;
               entity.AbsoluteWorkTime = Convert.ToDecimal(workSpan.TotalHours);
               entity.OvertimeLength = Convert.ToDecimal(workSpan.TotalHours);
               return;
           }
           TimeSpan absoluteSpan = totalTime - restTime;
           entity.AbsoluteWorkTime = Convert.ToDecimal(absoluteSpan.TotalHours.ToString("f2"));
           //暂时不考虑开始时间在18:00以后的加班时长计算，18：00以后开始上班的就加班时长就为0  
           if (beginTime > getoffTime || endTime < OvertimeTime)
           {
               entity.OvertimeLength = 0m;
               return;
           }
           //加班时长按半小时半小时计算
           TimeSpan overtimeSpan = endTime - getoffTime;
           //半小时个数
           double halfHours = Math.Floor(overtimeSpan.TotalHours * 2);
           entity.OvertimeLength = Convert.ToDecimal(halfHours) / 2m;
       }

       public static void CallWithTimeout(Action action, int timeoutMilliseconds)
       {
           Thread threadToKill = null;
           Action wrappedAction = () =>
           {
               threadToKill = Thread.CurrentThread;
               action();
           };

           IAsyncResult result = wrappedAction.BeginInvoke(null, null);
           if (result.AsyncWaitHandle.WaitOne(timeoutMilliseconds))
           {
               wrappedAction.EndInvoke(result);
           }
           else
           {
               threadToKill.Abort();
               LogHelper.Error(typeof(ImportAttendanceData), "超时抛出");
               //throw new TimeoutException();
           }
       }

    }
    
}